package com.xuanzheng.company.service.impl;

import com.xuanzheng.company.dao.EmployeePerformanceDao;
import com.xuanzheng.company.dao.impl.EmployeePerformanceDaoImpl;
import com.xuanzheng.company.entity.AttendanceSetting;
import com.xuanzheng.company.entity.EmployeePerformance;
import com.xuanzheng.company.service.AttendanceSettingService;
import com.xuanzheng.company.service.EmployeePerformanceService;
import com.xuanzheng.company.util.DBUtil;

import java.sql.*;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;

public class EmployeePerformanceServiceImpl implements EmployeePerformanceService {
    private EmployeePerformanceDao employeePerformanceDao;
    private AttendanceSettingService attendanceSettingService;
    
    public EmployeePerformanceServiceImpl() {
        this.employeePerformanceDao = new EmployeePerformanceDaoImpl();
        this.attendanceSettingService = new AttendanceSettingServiceImpl();
    }

    @Override
    public boolean savePerformance(EmployeePerformance performance) {
        return employeePerformanceDao.save(performance) > 0;
    }

    @Override
    public boolean updatePerformance(EmployeePerformance performance) {
        return employeePerformanceDao.update(performance) > 0;
    }

    @Override
    public EmployeePerformance getPerformanceById(String id) {
        return employeePerformanceDao.getById(id);
    }

    @Override
    public EmployeePerformance getPerformanceByUserIdAndYearMonth(String userId, int year, int month) {
        return employeePerformanceDao.getByUserIdAndYearMonth(userId, year, month);
    }

    @Override
    public List<EmployeePerformance> getPerformancesByCompanyIdAndYearMonth(String companyId, int year, int month) {
        return employeePerformanceDao.getByCompanyIdAndYearMonth(companyId, year, month);
    }

    @Override
    public List<EmployeePerformance> getPerformancesByUserId(String userId) {
        return employeePerformanceDao.getByUserId(userId);
    }

    @Override
    public boolean deletePerformance(String id) {
        return employeePerformanceDao.delete(id) > 0;
    }

    @Override
    public boolean uploadCurrentMonthPerformances(String companyId, int year, int month) {
        Connection conn = null;
        boolean success = true;
        
        try {
            conn = DBUtil.getConnection();
            conn.setAutoCommit(false); // 开启事务
            
            // 获取绩点设置
            AttendanceSetting setting = attendanceSettingService.getByCompanyId(companyId);
            if (setting == null) {
                return false;
            }
            
            // 获取当前月份的第一天和最后一天
            YearMonth yearMonth = YearMonth.of(year, month);
            LocalDate firstDay = yearMonth.atDay(1);
            LocalDate lastDay = yearMonth.atEndOfMonth();
            
            // 获取公司所有员工
            List<EmployeeInfo> employees = getCompanyEmployees(conn, companyId);
            
            for (EmployeeInfo employee : employees) {
                // 计算员工当月打卡时长
                double attendanceHours = calculateAttendanceHours(conn, employee.userId, companyId, firstDay, lastDay);
                
                // 计算员工当月任务平均评分
                double avgTaskScore = calculateAverageTaskScore(conn, employee.userId, companyId, firstDay, lastDay);
                
                // 计算绩点
                double performance = calculatePerformance(attendanceHours, avgTaskScore, setting);
                
                // 格式化绩点，保留一位小数
                DecimalFormat df = new DecimalFormat("0.0");
                double formattedPerformance = Double.parseDouble(df.format(performance));
                
                // 检查是否已存在该员工该月份的绩点记录
                EmployeePerformance existingPerformance = employeePerformanceDao.getByUserIdAndYearMonth(
                        employee.userId, year, month);
                
                if (existingPerformance != null) {
                    // 更新现有记录
                    existingPerformance.setAttendanceHours(attendanceHours);
                    existingPerformance.setAvgTaskScore(avgTaskScore);
                    existingPerformance.setPerformance(formattedPerformance);
                    // 更新员工姓名和职位，确保数据始终是最新的
                    existingPerformance.setEmployeeName(employee.name);
                    existingPerformance.setPosition(employee.position);
                    if (employeePerformanceDao.update(existingPerformance) <= 0) {
                        success = false;
                        break;
                    }
                } else {
                    // 创建新记录
                    EmployeePerformance newPerformance = new EmployeePerformance();
                    newPerformance.setCompanyId(companyId);
                    newPerformance.setUserId(employee.userId);
                    newPerformance.setEmployeeNumber(employee.employeeNumber);
                    newPerformance.setEmployeeName(employee.name);
                    newPerformance.setPosition(employee.position);
                    newPerformance.setYear(year);
                    newPerformance.setMonth(month);
                    newPerformance.setAttendanceHours(attendanceHours);
                    newPerformance.setAvgTaskScore(avgTaskScore);
                    newPerformance.setPerformance(formattedPerformance);
                    
                    if (employeePerformanceDao.save(newPerformance) <= 0) {
                        success = false;
                        break;
                    }
                }
            }
            
            if (success) {
                conn.commit();
            } else {
                conn.rollback();
            }
            
            return success;
        } catch (Exception e) {
            e.printStackTrace();
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
            return false;
        } finally {
            if (conn != null) {
                try {
                    conn.setAutoCommit(true);
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    private List<EmployeeInfo> getCompanyEmployees(Connection conn, String companyId) throws SQLException {
        List<EmployeeInfo> employees = new ArrayList<>();
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try {
            String sql = "SELECT ce.user_id, u.name, ce.employee_number, ce.position " +
                    "FROM company_employee ce " +
                    "JOIN user u ON ce.user_id = u.id " +
                    "WHERE ce.company_id = ? AND ce.status = 1";
            
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, companyId);
            rs = pstmt.executeQuery();
            
            while (rs.next()) {
                EmployeeInfo employee = new EmployeeInfo();
                employee.userId = rs.getString("user_id");
                employee.name = rs.getString("name");
                employee.employeeNumber = rs.getString("employee_number");
                employee.position = rs.getString("position");
                employees.add(employee);
            }
        } finally {
            if (rs != null) rs.close();
            if (pstmt != null) pstmt.close();
        }
        
        return employees;
    }
    
    private double calculateAttendanceHours(Connection conn, String userId, String companyId, 
                                          LocalDate startDate, LocalDate endDate) throws SQLException {
        double totalHours = 0.0;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try {
            // 查询员工当月打卡记录
            String sql = "SELECT check_in_time, check_out_time " +
                    "FROM attendance_record " +
                    "WHERE user_id = ? AND company_id = ? " +
                    "AND attendance_date BETWEEN ? AND ?";
            
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, userId);
            pstmt.setString(2, companyId);
            pstmt.setDate(3, Date.valueOf(startDate));
            pstmt.setDate(4, Date.valueOf(endDate));
            rs = pstmt.executeQuery();
            
            // 计算每天的工作时长并累加
            while (rs.next()) {
                Timestamp checkInTime = rs.getTimestamp("check_in_time");
                Timestamp checkOutTime = rs.getTimestamp("check_out_time");
                
                if (checkInTime != null && checkOutTime != null) {
                    // 计算工作时长（小时）
                    double hours = (checkOutTime.getTime() - checkInTime.getTime()) / (1000.0 * 60 * 60);
                    totalHours += hours;
                }
            }
        } finally {
            if (rs != null) rs.close();
            if (pstmt != null) pstmt.close();
        }
        
        return totalHours;
    }
    
    private double calculateAverageTaskScore(Connection conn, String userId, String companyId,
                                           LocalDate startDate, LocalDate endDate) throws SQLException {
        double totalScore = 0.0;
        int taskCount = 0;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        
        try {
            // 查询员工当月已完成的任务评分
            String sql = "SELECT score " +
                    "FROM task " +
                    "WHERE employee_id = ? AND company_id = ? AND status = 2 " +
                    "AND DATE(confirm_time) BETWEEN ? AND ?";
            
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, userId);
            pstmt.setString(2, companyId);
            pstmt.setDate(3, Date.valueOf(startDate));
            pstmt.setDate(4, Date.valueOf(endDate));
            rs = pstmt.executeQuery();
            
            // 计算任务评分总和和数量
            while (rs.next()) {
                int score = rs.getInt("score");
                totalScore += score;
                taskCount++;
            }
        } finally {
            if (rs != null) rs.close();
            if (pstmt != null) pstmt.close();
        }
        
        // 计算平均分，如果没有任务则返回0
        return taskCount > 0 ? totalScore / taskCount : 0;
    }
    
    private double calculatePerformance(double attendanceHours, double avgTaskScore, AttendanceSetting setting) {
        // 获取设置参数
        double maxAttendanceHours = setting.getMaxAttendanceHours();
        double attendancePercentage = setting.getAttendancePercentage();
        double taskPercentage = setting.getTaskPercentage();
        
        // 计算打卡部分的绩点（满分5分），如果打卡时长超过满分，则按满分计算
        double effectiveAttendanceHours = Math.min(attendanceHours, maxAttendanceHours);
        double attendancePerformance = (effectiveAttendanceHours / maxAttendanceHours) * attendancePercentage * 5;
        
        // 计算任务评分部分的绩点（满分5分）
        double taskPerformance = (avgTaskScore / 10) * taskPercentage * 5;
        
        // 总绩点
        double totalPerformance = attendancePerformance + taskPerformance;
        
        // 限制绩点范围在0-5之间
        return Math.max(0, Math.min(5, totalPerformance));
    }
    
    // 员工信息内部类
    private static class EmployeeInfo {
        String userId;
        String name;
        String employeeNumber;
        String position;
    }
} 